Tópicos Especiais em Estatística Computacional
Universidade Federal de Pernambuco (UFPE)
2025-08-12
Contexto: A computação onipresente gera fluxos massivos de dados inerciais (Smartphones, Smartwatches).
O Desafio: Classificar atividades complexas a partir de séries temporais ruidosas e estocásticas.
. . .
Abordagem Proposta: Substituir a Feature Engineering manual clássica por Deep Learning End-to-End.
Objetivo
Comparar rigorosamente o desempenho de redes Recorrentes (LSTM) vs. Convolucionais (1D-CNN) no dataset UCI HAR.
Antes da modelagem, é fundamental entender a volumetria e a estrutura física dos dados capturados.
Divisão do Conjunto de Dados (Hold-out):
| Conjunto | Quantidade de Amostras (\(N\)) | Proporção |
|---|---|---|
| Treinamento | 7.352 janelas | 70% |
| Teste | 2.947 janelas | 30% |
| Total | 10.299 janelas | 100% |
Os sinais brutos provêm do Acelerômetro e Giroscópio triaxiais.
| Índice | Sensor | Eixo | Descrição Física |
|---|---|---|---|
| 0-2 | Body Acc | \(X, Y, Z\) | Aceleração do corpo (sem gravidade). |
| 3-5 | Gyro | \(X, Y, Z\) | Velocidade angular (giro). |
| 6-8 | Total Acc | \(X, Y, Z\) | Aceleração bruta (inclui gravidade). |
Exemplo de estrutura tabular de uma única janela (\(t=1 \dots 128\)):
| Time Step (\(t\)) | Body_Acc_X | Body_Acc_Y | … | Gyro_Z | Total_Acc_Z |
|---|---|---|---|---|---|
| \(t_1\) | 0.002 | -0.005 | … | 0.012 | 0.982 |
| \(t_2\) | 0.004 | -0.008 | … | 0.015 | 0.985 |
| \(t_3\) | 0.001 | -0.002 | … | 0.011 | 0.979 |
| \(\vdots\) | \(\vdots\) | \(\vdots\) | \(\ddots\) | \(\vdots\) | \(\vdots\) |
| \(t_{128}\) | 0.003 | -0.001 | … | 0.014 | 0.981 |
Para alimentar as redes neurais, os dados foram estruturados em janelas deslizantes.
\[X \in \mathbb{R}^{N \times 128 \times 9}\]
1. Dimensão Temporal (Time Steps): * Frequência: 50Hz. * Tamanho da Janela: 128 passos. * Duração Física: \(\frac{128}{50} = \mathbf{2.56 \text{ segundos}}\). * Overlap (50%): A janela desliza a cada 64 passos para manter a continuidade do movimento.
2. Dimensão de Features (Canais): As 9 variáveis de entrada (\(X_t\)): 1. Aceleração Corporal (\(x, y, z\)) 2. Aceleração Total (\(x, y, z\)) \(\rightarrow\) Inclui Gravidade! 3. Giroscópio (\(x, y, z\))
Utilizamos One-Hot Encoding para todas as 6 classes, evitando ordinalidade numérica.
| ID | Atividade | Vetor One-Hot (Target) |
|---|---|---|
| 1 | Caminhando | [1, 0, 0, 0, 0, 0] |
| 2 | Subindo Escadas | [0, 1, 0, 0, 0, 0] |
| 3 | Descendo Escadas | [0, 0, 1, 0, 0, 0] |
| 4 | Sentado | [0, 0, 0, 1, 0, 0] |
| 5 | Em Pé | [0, 0, 0, 0, 1, 0] |
| 6 | Deitado | [0, 0, 0, 0, 0, 1] |
A rede processa a matriz de entrada \(X \in \mathbb{R}^{128 \times 9}\) passo a passo.
1. O Fatiamento (\(x_t\)) No instante \(t\), extraímos a linha correspondente às 9 variáveis e a transpomos.
\[x_t = (X_{t, :})^T \in \mathbb{R}^{9 \times 1}\]
2. A Fusão de Contexto (\(v_{in}\)) Para processar o “agora” (\(x_t\)) junto com o “passado” (\(h_{t-1}\)), concatenamos os vetores verticalmente:
\[v_{in} = \begin{bmatrix} h_{t-1} \\ x_t \end{bmatrix}\]
Como transformamos o vetor \(v_{in}\) (137) de volta para o tamanho da memória (128)?
Matrizes de Pesos (\(W\)) Cada portão possui sua própria matriz para realizar a projeção linear: \[W_{\{f,i,c,o\}} \in \mathbb{R}^{128 \times 137}\]
Cálculo Dimensional (Álgebra Linear): \[(128 \times 137) \cdot (137 \times 1) = (128 \times 1)\]
Equações dos 4 Portões: Geram vetores de controle \(\in \mathbb{R}^{128}\).
O fechamento do ciclo no passo \(t\) e a propagação do sinal.
1. Estado da Célula (\(C_t\)): Soma linear (preserva o gradiente). \[C_t = (f_t \odot C_{t-1}) + (i_t \odot \tilde{C}_t)\] Dimensão: \(\mathbb{R}^{128 \times 1}\)
2. Saída / Estado Oculto (\(h_t\)): \[h_t = o_t \odot \tanh(C_t)\] Dimensão: \(\mathbb{R}^{128 \times 1}\)
Destino do Vetor \(h_t\):
\[x_t^{(Layer2)} = h_t^{(Layer1)}\]
Acompanhe a transformação das dimensões do tensor \(X\) (batch_size omitido para clareza).
| Etapa | Operação | Dimensão de Entrada | Dimensão de Saída | Explicação |
|---|---|---|---|---|
| Input | Janela Deslizante | \((128, 9)\) | \((128, 9)\) | 128 instantes, 9 sensores. |
| Layer 1 | LSTM (128 units) | \((128, 9)\) | \((128, 128)\) | return_sequences=True. Gera um vetor de 128 features para cada instante \(t\). |
| Layer 2 | LSTM (64 units) | \((128, 128)\) | \((64)\) | return_sequences=False. Apenas o último estado oculto (\(h_{128}\)) é retornado. |
| Classificador | Dense (Linear) | \((64)\) | \((6)\) | \(z = W_{out} \cdot h_{final} + b\). Gera os Logits. |
| Probabilidade | Softmax | \((6)\) | \((6)\) | \(\hat{y}_i = \frac{e^{z_i}}{\sum e^{z_j}}\). Soma = 1. |
Na série temporal, o filtro desliza no tempo (\(t\)), mas cobre todos os sensores (\(D\)) simultaneamente.
Entrada: \(X \in \mathbb{R}^{128 \times 9}\)
O Kernel Único (\(W\)): Para capturar correlações entre sensores, o kernel tem a profundidade da entrada. Se \(K=3\) (janela de tempo):
\[W \in \mathbb{R}^{3 \times 9}\]
A Operação de Deslizamento: O kernel computa o produto escalar cobrindo a matriz \(3 \times 9\) atual, depois desliza 1 passo (\(S=1\)).
Multiplicidade
Como definimos 64 filtros, existem 64 matrizes \(W\) distintas, gerando 64 mapas de características (Feature Maps) independentes.
Para um único filtro \(m\) (dentre os 64), o valor de saída em \(t\) é a soma total.
Equação Detalhada: \[z_t^{[m]} = \sigma \left( \sum_{i=0}^{K-1} \sum_{c=0}^{D-1} x_{(t+i), c} \cdot w_{i, c}^{[m]} + b^{[m]} \right)\]
Saída da Camada (Feature Maps): Cada filtro gera um vetor temporal. Empilhando os 64 filtros: \[\text{Output} \in \mathbb{R}^{126 \times 64}\]
Como a rede transita do sinal bruto para a classificação?
1. Redução Temporal (Pooling): Após a convolução, o MaxPool (\(P=2\)) divide o tempo pela metade. \[L_{out} = \lfloor \frac{126}{2} \rfloor = 63\] Saída do Bloco 1: \(\mathbb{R}^{63 \times 64}\)
2. Adaptação do Próximo Kernel (Bloco 2): A entrada agora tem profundidade 64 (não mais 9). O novo kernel (\(K=3\)) deve se adaptar: \[W_{Bloco2} \in \mathbb{R}^{3 \times 64}\]
Final da Rede (GAP)
No último estágio (\(28 \times 256\)), o Global Average Pooling condensa o tempo em uma média simples, gerando o vetor final \(\mathbb{R}^{256}\) para a Softmax.
Note como a dimensão temporal (\(L\)) diminui enquanto a profundidade (\(D\) - canais) aumenta.
| Camada | Configuração | Entrada \((L \times D)\) | Saída \((L \times D)\) | Parâmetros (\(W\)) |
|---|---|---|---|---|
| Input | Sinal Bruto | \(128 \times 9\) | \(128 \times 9\) | - |
| Conv1D_1 | 64 Filtros, \(K=3\) | \(128 \times 9\) | \(126 \times 64\) | \(3 \times 9 \times 64 + 64\) |
| MaxPool_1 | Pool=2 | \(126 \times 64\) | \(63 \times 64\) | - |
| Conv1D_2 | 128 Filtros, \(K=3\) | \(63 \times 64\) | \(61 \times 128\) | \(3 \times 64 \times 128 + 128\) |
| MaxPool_2 | Pool=2 | \(61 \times 128\) | \(30 \times 128\) | - |
| GAP | Global Avg Pooling | \(30 \times 128\) | \(128\) | Média simples no eixo \(t\). |
| Output | Dense + Softmax | \(128\) | \(6\) | Classificação Final. |
A camada final recebe o vetor de features latentes \(z\) (seja \(h_{128}\) da LSTM ou o GAP da CNN).
\[z = [z_1, z_2, z_3, z_4, z_5, z_6]\]
A probabilidade da classe “Caminhando” (índice 1) é:
\[P(y=1|X) = \frac{e^{z_1}}{e^{z_1} + e^{z_2} + e^{z_3} + e^{z_4} + e^{z_5} + e^{z_6}}\]
Interpretação
O modelo não diz “É caminhada”. Ele diz: “Tenho 98% de certeza que é caminhada, 1% que é subindo escada e 1% ruído”. A decisão é o argmax.
Estratégia: Empilhamento de camadas recorrentes para abstração progressiva temporal.
Fluxo de Dados: 1. Entrada: Sequência crua. 2. LSTM 1: Extrai features de baixo nível mantendo a sequência (return_seq=True). 3. LSTM 2: Comprime a sequência temporal em um único vetor de contexto (return_seq=False). 4. Dense: Classificação não-linear.
| Camada | Configuração | Output Shape \((N, T, D)\) |
|---|---|---|
| Input | Janela 2.56s | \((None, 128, 9)\) |
| LSTM 1 | 128 Units, \(\tanh\) | \((None, 128, 128)\) |
| Dropout | Rate = 0.3 | \((None, 128, 128)\) |
| LSTM 2 | 64 Units, \(\tanh\) | \((None, \mathbf{64})\) |
| Dropout | Rate = 0.3 | \((None, 64)\) |
| Dense | 64 Units, ReLU | \((None, 64)\) |
| Output | Softmax (6 classes) | \((None, 6)\) |
Total de Parâmetros: ~124.870
Estratégia: Extração de features locais com redução espacial agressiva via Pooling.
Fluxo de Dados: 1. Blocos Conv: 3 estágios de (Convolução + ReLU + MaxPool). 2. Aprofundamento: O número de filtros dobra a cada bloco (64 \(\to\) 128 \(\to\) 256). 3. GAP: Redução drástica de dimensão (média temporal) antes da classificação.
| Bloco | Camada | Config (Kernel=3) | Output Shape |
|---|---|---|---|
| 1 | Conv1D | 64 Filtros | \((126, 64)\) |
| MaxPool | Size=2 | \((63, 64)\) | |
| 2 | Conv1D | 128 Filtros | \((61, 128)\) |
| MaxPool | Size=2 | \((30, 128)\) | |
| 3 | Conv1D | 256 Filtros | \((28, 256)\) |
| GAP | Global Avg | \((None, \mathbf{256})\) | |
| Out | Dense | Softmax | \((None, 6)\) |
Total de Parâmetros: ~143.686
| Parâmetro | Configuração | Justificativa |
|---|---|---|
| Otimizador | Adam | Momento Adaptativo para convergência rápida. |
| Learning Rate | 0.001 | Padrão inicial, ajustado dinamicamente. |
| Inicialização | He Normal | Ideal para função de ativação ReLU. |
| Scheduler | ReduceLROnPlateau |
Ajuste fino (fine-tuning) em mínimos locais. |
| Critério Parada | EarlyStopping |
Monitoramento da Val Loss (Patience=12). |
Avaliação em 2.947 amostras independentes.
| Métrica | Stacked LSTM | Pure 1D-CNN |
|---|---|---|
| Acurácia Global | 90% | 93% |
| Precision (Média) | 0.90 | 0.94 |
| F1-Score (Média) | 0.90 | 0.93 |
Veredito
A 1D-CNN é superior tanto em acurácia quanto em eficiência computacional para janelas curtas (2.56s).
Obrigado!